package com.wqj.ride.happyriding.service

import android.app.Notification
import android.app.PendingIntent
import android.content.Intent
import android.graphics.BitmapFactory
import android.os.Binder
import android.os.Handler
import android.os.IBinder
import android.util.Log
import com.amap.api.location.AMapLocation
import com.amap.api.navi.enums.NaviType
import com.amap.api.navi.model.NaviInfo
import com.wqj.ride.happyriding.R
import com.wqj.ride.happyriding.bean.DataBean
import com.wqj.ride.happyriding.bluetooth.bt.manager.BtManager
import com.wqj.ride.happyriding.nav.activity.CustomRouteNaviActivity
import com.wqj.ride.happyriding.base.BaseNavService
import com.wqj.ride.happyriding.service.listener.NaviInfoUpdateListener
import com.wqj.ride.happyriding.service.listener.TimerListener


class HappyRiddingService : BaseNavService() {
    lateinit var mBinder: MyBinder
    val mHandler: Handler = Handler()
    var mNaviInfoUpdateListener: NaviInfoUpdateListener? = null
    var mTimerListener: TimerListener?= null
    var mNaviStatus: Int = NAVI_STATUS_STOPPED
    var mNotificationBuilder: Notification.Builder? = null
    var mNotification: Notification? = null

    class MyBinder(var ctx: HappyRiddingService): Binder() {
        lateinit var c: HappyRiddingService
        var timeValue: Long = 0
        var timerStatus: Int = 0
        var isFistTimeStart: Boolean = true             // 第一次按开始按钮

        interface LocationUpdateCallBack {
            fun onLocationUpdate(value: AMapLocation)
        }

        init {
            c = ctx
            timerStatus = TIMER_STOP
        }

        var timerTask: Runnable = object: Runnable {
            override fun run() {
                when (timerStatus) {
                    TIMER_START -> {
                        timeValue++
                        ctx.mTimerListener?.onTimerUpdate(timeValue)
                        c.mHandler.postDelayed(this, 1000)
                    }
                }
            }
        }
        fun setTimerListener(c: TimerListener) {
            ctx.mTimerListener = c
        }

        fun setNaviInfoUpdateListener(listener: NaviInfoUpdateListener) {
            ctx.mNaviInfoUpdateListener = listener
        }

        fun removeNaviInfoUpdateListener() {
            ctx.mNaviInfoUpdateListener = null
        }

        fun startNavi(naviType: Int) {
            if (NAVI_STATUS_NAVING == ctx.mNaviStatus) {
                Log.d(TAG, "already in naving status")
                return
            }
            if (NaviType.EMULATOR == naviType) {
                ctx.mAMapNavi.setEmulatorNaviSpeed(60)
            }
            ctx.mNaviStatus = NAVI_STATUS_NAVING
            ctx.mAMapNavi.startNavi(naviType)
            ctx.mNotificationBuilder!!.setContentText("导航中")
            ctx.startForeground(110, ctx.mNotification)
            startTimer()
        }

        fun pauseNavi() {
            if (NAVI_STATUS_NAVING != ctx.mNaviStatus) {
                Log.d(TAG, "not in naving status, no need pause")
                return
            }
            ctx.mNaviStatus = NAVI_STATUS_PAUSED
            ctx.mAMapNavi.pauseNavi()
            ctx.mNotificationBuilder!!.setContentText("导航暂停中")
            ctx.startForeground(110, ctx.mNotification)
            pauseTimer()
        }

        fun resumeNavi() {
            if (NAVI_STATUS_PAUSED != ctx.mNaviStatus) {
                Log.d(TAG, "not in paused status, won't resume")
                return
            }
            ctx.mNaviStatus = NAVI_STATUS_NAVING
            ctx.mAMapNavi.resumeNavi()
            ctx.mNotificationBuilder!!.setContentText("导航中")
            ctx.startForeground(110, ctx.mNotification)
            startTimer()
        }

        fun stopNavi() {
            if (NAVI_STATUS_STOPPED == ctx.mNaviStatus) {
                Log.d(TAG, "already stopped")
                return
            }
            ctx.mNaviStatus = NAVI_STATUS_STOPPED
            ctx.mAMapNavi.stopNavi()
            ctx.stopForeground(true)
            stopTimer()
        }

        private fun startTimer() {
            when (timerStatus) {
                TIMER_PAUSE -> {

                }
                TIMER_STOP -> {
                    timeValue = 0
                }
                TIMER_START -> {
                    return
                }
            }
            timerStatus = TIMER_START
            c.mHandler.postDelayed(timerTask, 1000)
            if (isFistTimeStart) {
                isFistTimeStart = false
                DataBean.startTime = System.currentTimeMillis()
            }
        }
        private fun pauseTimer() {
            timerStatus = TIMER_PAUSE
        }
        private fun stopTimer() {
            timerStatus = TIMER_STOP
            isFistTimeStart = true
            DataBean.endTime = System.currentTimeMillis()
            DataBean.rideTime = timeValue
        }
    }

    override fun onCreate() {
        super.onCreate()
        mBinder = MyBinder(this)
    }


    override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int {
        Log.d(TAG, "onStartCommand")

        mNotificationBuilder = Notification.Builder(applicationContext)

        val intent: Intent = Intent(this, CustomRouteNaviActivity().javaClass)

        mNotificationBuilder!!.setContentIntent(PendingIntent
                .getActivity(this, 0, intent, 0)) // pending intent
                .setLargeIcon(BitmapFactory.decodeResource(this.getResources(),
                R.mipmap.app_icon)) // 设置下拉列表中的图标(大图标)
                .setContentTitle("骑行导航") // 设置下拉列表里的标题
                .setSmallIcon(R.mipmap.ic_launcher) // 设置状态栏内的小图标
                .setContentText("服务运行中") // 设置上下文内容
                .setWhen(System.currentTimeMillis()) // 设置该通知发生的时间

        mNotification = mNotificationBuilder!!.build()
        mNotification!!.defaults = Notification.DEFAULT_SOUND //设置为默认的声音

        startForeground(110, mNotification) // 开始前台服务

        return super.onStartCommand(intent, flags, startId)
    }

    override fun onDestroy() {
        super.onDestroy()

        stopForeground(true) // 停止前台服务--参数：表示是否移除之前的通知
    }

    override fun onBind(intent: Intent): IBinder? {
        return mBinder
    }

    override fun onUnbind(intent: Intent?): Boolean {
        return super.onUnbind(intent)
    }

    override fun onNaviInfoUpdate(naviInfo: NaviInfo) {
        if (BtManager.getInstance().isConnected) {
            sendNaviData2Stm32(naviInfo)
        }
        mNaviInfoUpdateListener?.onNaviInfoUpdate(naviInfo)
    }

    internal fun sendNaviData2Stm32(naviInfo: NaviInfo) {
        val data = ByteArray(16)
        val iconType = naviInfo.iconType
        val retainDistance = naviInfo.curStepRetainDistance
        val remainUnit = UNIT_M
        var totalRemainUnit = UNIT_M
        val speed = naviInfo.getCurrentSpeed()
        var totalRetainDistance = naviInfo.pathRetainDistance
        val totalRetainTime = naviInfo.pathRetainTime

        if (totalRetainDistance > 1000) {
            totalRetainDistance = totalRetainDistance / 1000
            totalRemainUnit = UNIT_KM
        } else {
            totalRemainUnit = UNIT_M
        }

        data[0] = 0xEF.toByte()   // head1
        data[1] = 0xEF.toByte()   // head2

        data[2] = 0x00.toByte()

        data[3] = iconType.toByte()

        data[5] = (retainDistance shr 8).toByte()
        data[4] = retainDistance.toByte()
        data[7] = 0x00   // unit high
        data[6] = remainUnit

        data[9] = (totalRetainDistance shr 8).toByte()
        data[8] = totalRetainDistance.toByte()
        data[11] = 0x00    // unit high
        data[10] = totalRemainUnit // unit low

        data[12] = 0x00    // crc high
        data[13] = 0x00    // crc low

        data[14] = 0xFE.toByte()  // tail1
        data[15] = 0xFE.toByte()  // tail2

        BtManager.getInstance().send(data)

    }

    companion object {
        val TAG: String = "HappyRiddingService"
        val TIMER_START: Int = 0
        val TIMER_PAUSE: Int = 1
        val TIMER_STOP: Int = 2
        val UNIT_M: Byte = 0
        val UNIT_KM: Byte = 1

        val NAVI_STATUS_NAVING: Int = 0
        val NAVI_STATUS_PAUSED: Int = 1
        val NAVI_STATUS_STOPPED: Int = 2
        val NAVI_STATUS_FINISHED: Int = 3
    }
}
